package com.gjzhao.fmmall.config;

import cn.hutool.core.util.ObjectUtil;
import com.gjzhao.fmmall.vo.RespCode;
import com.gjzhao.fmmall.vo.RespResultVO;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

/**
 * @Description: 使用aop切面：实现参数校验
 * @Author: gjzhao
 * @Date Created in 2022-01-24 10:42 上午
 */
@Aspect //标识当前类为一个切面容器
@Component
@Order(2)  //定义Spring容器加载bean的顺序
public class BindingResultAspect {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("execution(public * com.gjzhao.fmmall.controller.*.*(..))")
    public void bindingResult() {

    }

    /**
     * 使用aop切面，获取注入的 BindingResult，校验参数校验结果
     * - 1.如果校验通过，则放行
     * - 2.如果校验不通过，封装错误信息进行返回
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("bindingResult()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        //获取参数对象
        Object[] args = joinPoint.getArgs();

        for (Object arg : args) {
            if (arg instanceof BindingResult) {
                BindingResult result = (BindingResult) arg;

                // 判断校验结果是否为true
                if (result.hasErrors()) {

                    logger.info("---参数校验结果,fail----");

                    //获取错误消息,如果有则返回错误消息
                    FieldError fieldError = result.getFieldError();
                    if (ObjectUtil.isNotNull(fieldError)) {
                        return RespResultVO.failed(RespCode.FAILED, fieldError.getDefaultMessage());
                    } else {
                        return RespResultVO.failed(RespCode.FAILED);
                    }
                }

                logger.info("---参数校验结果,success----");
            }
        }
        return joinPoint.proceed();
    }
}
